<template>
  <div class="markdown-editor">
    <div class="editor-container">
      <!-- 左侧：Markdown 输入框 -->
      <textarea
          class="editor-input"
          v-model="markdownText"
          placeholder="请输入 Markdown 文本..."
      ></textarea>

      <!-- 右侧：Markdown 预览 -->
      <div class="preview" v-html="compiledMarkdown"></div>
    </div>
  </div>
</template>

<script setup>
import { ref, computed } from 'vue';

// Markdown 文本
const markdownText = ref('');

// 自定义 Markdown 解析函数
const parseMarkdown = (text) => {
  // 标题
  text = text.replace(/^# (.*$)/gm, '<h1>$1</h1>');
  text = text.replace(/^## (.*$)/gm, '<h2>$1</h2>');
  text = text.replace(/^### (.*$)/gm, '<h3>$1</h3>');

  // 粗体
  text = text.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>');
  text = text.replace(/__(.*?)__/g, '<strong>$1</strong>');

  // 斜体
  text = text.replace(/\*(.*?)\*/g, '<em>$1</em>');
  text = text.replace(/_(.*?)_/g, '<em>$1</em>');

  // 删除线
  text = text.replace(/~~(.*?)~~/g, '<del>$1</del>');

  // 无序列表
  text = text.replace(/^\s*\n\*/gm, '<ul>');
  text = text.replace(/^\* (.*$)/gm, '<li>$1</li>');
  text = text.replace(/<\/li>\s*<li>/g, '</li><li>');
  text = text.replace(/<\/li>\s*<\/ul>/g, '</li></ul>');

  // 有序列表
  text = text.replace(/^\s*\n\d+\./gm, '<ol>');
  text = text.replace(/^\d+\. (.*$)/gm, '<li>$1</li>');
  text = text.replace(/<\/li>\s*<li>/g, '</li><li>');
  text = text.replace(/<\/li>\s*<\/ol>/g, '</li></ol>');

  // 链接
  text = text.replace(/\[(.*?)\]\((.*?)\)/g, '<a href="$2">$1</a>');

  // 图片
  text = text.replace(/!\[(.*?)\]\((.*?)\)/g, '<img src="$2" alt="$1" />');

  // 代码块（支持语言标识）
  text = text.replace(/```(\w+)?\s*([\s\S]*?)```/g, (match, lang, code) => {
    // 根据语言标识高亮代码
    const highlightedCode = highlightCode(code, lang);
    return `<pre><code class="language-${lang || 'plaintext'}">${highlightedCode}</code></pre>`;
  });

  // 行内代码
  text = text.replace(/`(.*?)`/g, '<code>$1</code>');

  // 段落
  text = text.replace(/^\s*(\n)?(.+)/gm, (m) => {
    return /\<(\/)?(h\d|ul|ol|li|blockquote|pre|img)/.test(m) ? m : `<p>${m}</p>`;
  });

  // 换行
  text = text.replace(/\n$/g, '<br />');

  return text;
};

// 高亮代码块中的关键字
const highlightCode = (code, language) => {
  let keywords = [];
  if (language === 'javascript') {
    keywords = [
      'function', 'if', 'else', 'return', 'const', 'let', 'var', 'for', 'while', 'switch', 'case', 'break', 'continue',
      'class', 'new', 'this', 'typeof', 'instanceof', 'true', 'false', 'null', 'undefined', 'try', 'catch', 'throw',
      'import', 'export', 'default', 'async', 'await', 'Promise', 'console', 'log', 'error', 'warn', 'info',
    ];
  } else if (language === 'python') {
    keywords = [
      'def', 'if', 'else', 'elif', 'return', 'for', 'while', 'break', 'continue', 'class', 'self', 'try', 'except',
      'raise', 'import', 'from', 'as', 'True', 'False', 'None', 'and', 'or', 'not', 'in', 'is', 'lambda', 'with',
      'yield', 'print',
    ];
  }

  keywords.forEach((keyword) => {
    const regex = new RegExp(`\\b${keyword}\\b`, 'g');
    code = code.replace(regex, `<span class="keyword">${keyword}</span>`);
  });

  return code;
};

// 将 Markdown 转换为 HTML
const compiledMarkdown = computed(() => {
  return parseMarkdown(markdownText.value);
});
</script>

<style scoped>
.markdown-editor {
  width: 100%;
  height: 80%;
  padding: 10px;
}

.editor-container {
  display: flex;
  width: 100%;
  height: 100%;
  border: 1px solid #ccc;
  border-radius: 8px;
  overflow: hidden;
}

.editor-input {
  flex: 1;
  padding: 10px;
  font-family: 'Courier New', Courier, monospace;
  font-size: 14px;
  border: none;
  outline: none;
  resize: none;
  background-color: #f9f9f9;
}

.preview {
  flex: 1;
  padding: 10px;
  overflow-y: auto;
  border-left: 1px solid #ccc;
  background-color: #fff;
}

/* 代码块样式 */
pre {
  background-color: #f5f5f5;
  padding: 10px;
  border-radius: 4px;
  overflow-x: auto;
}

code {
  font-family: 'Courier New', Courier, monospace;
  font-size: 14px;
}

/* 关键字高亮 */
.keyword {
  color: #d73a49; /* 关键字颜色 */
}
</style>